//
//  XZTableView.m
//  BeautyBaoUnion
//
//  Created by 肖智 on 2016/10/26.
//  Copyright © 2016年 肖智. All rights reserved.
//

#import "XZTableView.h"
@interface XZTableView(){
    CGFloat _needScrollRange;
    CGPoint _lastPoint;
    CGPoint _currentPoint;
}
@property(nonatomic,strong)UILongPressGestureRecognizer *longGesture;
@property(nonatomic,strong)UIView   *snapView;
@property(nonatomic,strong)NSMutableArray *dataArray;
@property(nonatomic,strong)NSMutableArray *heightArray;
@property(nonatomic,strong)NSIndexPath *moveIndexPath;
@property(nonatomic,strong)CADisplayLink *displayLink;
@end
@implementation XZTableView

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
    self = [super initWithFrame:frame style:style];
    if(self){
        [self commonInit];
    }
    return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if(self){
        [self commonInit];
    }
    return self;
}
- (void)commonInit{
    _needScrollRange = 60;
    _longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongGesture:)];
    _longGesture.minimumPressDuration = 0.5;
    [self addGestureRecognizer:_longGesture];
}
- (void)handleLongGesture:(UILongPressGestureRecognizer *)gesture{
    switch (gesture.state) {
        case UIGestureRecognizerStateBegan:
        {
            [self xz_gestureBegin:gesture];
        }
            break;
        case UIGestureRecognizerStateChanged:
        {
            [self xz_gestureChanged:gesture];
        }
            break;
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateEnded:
        {
            [self xz_gestureEndOrCancled:gesture];
        }
            
            break;
        default:
            break;
    }
}
- (void)xz_gestureBegin:(UILongPressGestureRecognizer *)gesture{
    CGPoint pt = [gesture locationInView:gesture.view];
    _lastPoint = pt;
    NSIndexPath *selectIndex = [self indexPathForRowAtPoint:pt];
    if(!selectIndex){
        return;
    }
    [self startEdgeScroll];
    self.moveIndexPath = selectIndex;
    UITableViewCell *cell = [self cellForRowAtIndexPath:self.moveIndexPath];
    _snapView = [self snapshotViewWithInputView:cell];
    _snapView.layer.shadowColor = [UIColor grayColor].CGColor;
    _snapView.layer.masksToBounds = NO;
    _snapView.layer.cornerRadius = 0;
    _snapView.layer.shadowOffset = CGSizeMake(-5, 0);
    _snapView.layer.shadowOpacity = 0.4;
    _snapView.layer.shadowRadius = 5;
    _snapView.frame = cell.frame;
    cell.hidden = YES;
    [self addSubview:_snapView];
    [UIView animateWithDuration:0.25 animations:^{
        _snapView.center = CGPointMake(_snapView.center.x, pt.y);
    }];
}
- (void)xz_gestureChanged:(UILongPressGestureRecognizer *)gesture{
    CGPoint pt = [gesture locationInView:gesture.view];
    _currentPoint = pt;
    CGFloat deltX = _currentPoint.x-_lastPoint.x;
    CGFloat deltY = _currentPoint.y-_lastPoint.y;
    NSIndexPath *dstIndexPath = [self indexPathForRowAtPoint:pt];
    if(dstIndexPath&& ![_moveIndexPath isEqual:dstIndexPath]){
        [self switchCellWithSourceIndex:_moveIndexPath toDstIndex:dstIndexPath];
        self.moveIndexPath = dstIndexPath;
    }
        _snapView.center = CGPointMake(_snapView.center.x+deltX, pt.y);
    _lastPoint = _currentPoint;
}
- (void)xz_gestureEndOrCancled:(UILongPressGestureRecognizer *)gesture{
    [self stopEdgeScroll];
    UITableViewCell *cell = [self cellForRowAtIndexPath:self.moveIndexPath];
    [UIView animateWithDuration:0.25 animations:^{
        _snapView.frame = cell.frame;
    } completion:^(BOOL finished) {
        cell.hidden = NO;
        [_snapView removeFromSuperview];
        _snapView = nil;
    }];
}
- (void)switchCellWithSourceIndex:(NSIndexPath *)srcIndexPath toDstIndex:(NSIndexPath *)dstIndexPath{
    //只有一组
    [self.dataArray exchangeObjectAtIndex:srcIndexPath.row withObjectAtIndex:dstIndexPath.row];
    [self.heightArray exchangeObjectAtIndex:srcIndexPath.row withObjectAtIndex:dstIndexPath.row];
    //交换cell
    [self moveRowAtIndexPath:srcIndexPath toIndexPath:dstIndexPath];
}
- (void)startEdgeScroll{
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleEdgeScroll)];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)stopEdgeScroll{
    if(self.displayLink){
        [self.displayLink invalidate];
        self.displayLink = nil;
    }
}


- (void)handleEdgeScroll{
    if(self.bounds.size.height>=self.contentSize.height){
        return;
    }
    [self xz_gestureChanged:_longGesture];
    //对于某一个时刻，有个tableview需要自动上滑和下滑的临界条件
    CGFloat needScrollDownCondition = self.contentOffset.y+_needScrollRange;
    CGFloat needScrollupCondition = self.contentOffset.y+self.bounds.size.height-_needScrollRange;
    CGFloat snapViewTop = CGRectGetMinY(_snapView.frame);
    CGFloat snapViewBottom = CGRectGetMaxY(_snapView.frame);

    //上快要见底
    if(snapViewTop<=_needScrollRange){
        //如果已经下滑到底，不处理
        if(self.contentOffset.y<=0){
            return;
        }else{
            [self setContentOffset:CGPointMake(self.contentOffset.x, self.contentOffset.y-1) animated:NO];
            _snapView.center = CGPointMake(_snapView.center.x, _snapView.center.y-1);
        }
    }
    //下快要见底
    if(snapViewBottom>=self.bounds.size.height-_needScrollRange){
        if(self.contentOffset.y>=self.contentSize.height-self.bounds.size.height){
            return;
        }
        else{
            [self setContentOffset:CGPointMake(self.contentOffset.x, self.contentOffset.y+1) animated:NO];
            _snapView.center = CGPointMake(_snapView.center.x, _snapView.center.y+1);
        }
    }
    //顶部超过needScrollDownCondition，则tableview需要下滚动
    CGFloat moveDistance = 20;
    if(snapViewTop<needScrollDownCondition){
        [self setContentOffset:CGPointMake(self.contentOffset.x, self.contentOffset.y - moveDistance) animated:NO];
        _snapView.center = CGPointMake(_snapView.center.x, _snapView.center.y - moveDistance);
    }
    //底部低于needScrollupCondition，则tableview需要向上滚动

    else if(snapViewBottom>needScrollupCondition){
        [self setContentOffset:CGPointMake(self.contentOffset.x, self.contentOffset.y + moveDistance) animated:NO];
        _snapView.center = CGPointMake(_snapView.center.x, _snapView.center.y + moveDistance);
    }
}
- (UIView *)snapshotViewWithInputView:(UIView *)inputView
{
    UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, NO, 0);
    [inputView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    UIView *snapshot = [[UIImageView alloc] initWithImage:image];
    return snapshot;
}
- (NSMutableArray *)dataArray{
    if(!_dataArray){
        if(_xz_dataSource&&[_xz_dataSource respondsToSelector:@selector(dataSourceForXZTableView:)]){
            _dataArray = [_xz_dataSource dataSourceForXZTableView:self];
        }else{
            _dataArray = [NSMutableArray arrayWithCapacity:0];
        }
    }
    return _dataArray;
}
- (NSMutableArray *)heightArray{
    if(!_heightArray){
        if(_xz_dataSource&&[_xz_dataSource respondsToSelector:@selector(heightArrayForXZTableView:)]){
            _heightArray = [_xz_dataSource heightArrayForXZTableView:self];
        }else{
            _heightArray = [NSMutableArray arrayWithCapacity:0];
        }
    }
    return _heightArray;
}
@end
